using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Furion;
using NewLife.Caching;

namespace EventMsg;

public class SyncEventConsistency : ISyncEventConsistency
{
	private static readonly ICache _cache = App.GetService(typeof(ICache)) as ICache;

	/// <summary>
	/// 支持最大的数据量请求
	/// </summary>
	private SemaphoreSlim _maxEvent;

	private SemaphoreSlim _eventLock = new SemaphoreSlim(1, 1);

	private IComparer<string> comparer = null;

	/// <summary>
	/// 事件信息
	/// </summary>
	private ConcurrentDictionary<string, EventMessage> Events { get; set; }

	public SyncEventConsistency(int maxPesponse)
	{
		_maxEvent = new SemaphoreSlim(maxPesponse, maxPesponse);
		Events = new ConcurrentDictionary<string, EventMessage>();
	}

	/// <summary>
	/// 新增执行任务
	/// </summary>
	/// <param name="name">任务名称</param>
	/// <returns></returns>
	public async Task<EventParameterResponse<string>> AddEventAsync(string name)
	{
		LoggerWrite.Debug("新增任务" + name);
		EventParameterResponse<string> eventInitAdd = new EventParameterResponse<string>
		{
			Code = EventEnum.Wait,
			Message = "执行成功"
		};
		try
		{
			if (string.IsNullOrEmpty(name))
			{
				eventInitAdd.Code = EventEnum.Fail;
				eventInitAdd.Message = "任务名称不能为空";
				return eventInitAdd;
			}
			if (Events.ContainsKey(name) || _cache.ContainsKey(name))
			{
				eventInitAdd.Code = EventEnum.Fail;
				eventInitAdd.Message = "当前任务已被注册" + name;
				return eventInitAdd;
			}
			bool free = await _maxEvent.WaitAsync(10000);
			LoggerWrite.Debug("当前可用剩余" + _maxEvent.CurrentCount);
			if (!free)
			{
				eventInitAdd.Code = EventEnum.Fail;
				eventInitAdd.Message = "当前执行超时,没有多余的空间,请稍后再试";
				return eventInitAdd;
			}
			if (_cache.Add(name, "", 60))
			{
				Events.TryAdd(name, new EventMessage
				{
					CreateTime = DateTime.Now,
					EventSlim = new ManualResetEventSlim(),
					MessageName = name,
					State = EventEnum.Wait
				});
				return eventInitAdd;
			}
			eventInitAdd.Code = EventEnum.Fail;
			eventInitAdd.Message = "异常请重新添加";
			return eventInitAdd;
		}
		catch (Exception ex2)
		{
			Exception ex = ex2;
			eventInitAdd.Code = EventEnum.Error;
			eventInitAdd.Message = ex.Message ?? "";
			return eventInitAdd;
		}
		finally
		{
			int num;
			if (num >= 0)
			{
			}
		}
	}

	public EventMessage GetExcuteEvent(string name)
	{
		if (string.IsNullOrEmpty(name))
		{
			return null;
		}
		if (Events.TryGetValue(name, out var message))
		{
			return message;
		}
		return null;
	}

	/// <summary>
	/// 任务完成
	/// </summary>
	/// <param name="name">任务名称</param>
	/// <param name="body">任务内容</param>
	/// <param name="eventEnum">完成状态</param>
	/// <returns></returns>
	/// <exception cref="T:System.NotImplementedException"></exception>
	public void CompleteEvent(string name, object body, EventEnum eventEnum, string errormsg = "")
	{
		try
		{
			LoggerWrite.Debug("完成任务" + name + eventEnum.ToString() + errormsg + body);
			if (!string.IsNullOrEmpty(name) && Events.TryGetValue(name, out var message) && !message.IsDispose)
			{
				message.MessageBody = body;
				message.State = eventEnum;
				message.EventSlim.Set();
			}
		}
		finally
		{
			CloseEvent(name);
		}
	}

	/// <summary>
	/// 关闭移除
	/// </summary>
	/// <param name="name"></param>
	private void CloseEvent(string name)
	{
		if (!string.IsNullOrEmpty(name) && Events.TryRemove(name, out var message))
		{
			_cache.Remove(name);
			message.DisPose();
			LoggerWrite.Debug("当前剩余数量" + _maxEvent.Release());
		}
	}

	/// <summary>
	/// 执行等待任务
	/// </summary>
	/// <param name="name">任务名称</param>
	/// <param name="startEvent">需要执行的事件</param>
	/// <param name="actionTimeOutCallBack">执行超时调用回调</param>
	/// <param name="timeOut">超时时间 默认40s</param>
	/// <returns></returns>
	public async Task<EventParameterResponse<T>> ExcuteEvent<T>(string name, Action startEvent, Action actionTimeOutCallBack, int timeOut = 40)
	{
		try
		{
			LoggerWrite.Debug("执行任务" + name);
			EventParameterResponse<T> response = new EventParameterResponse<T>
			{
				Code = EventEnum.Fail,
				Message = "执行成功"
			};
			if (Events.TryGetValue(name, out var message))
			{
				message.EventSlim.Reset();
				startEvent?.Invoke();
				if (message.EventSlim.Wait(timeOut * 1000))
				{
					EventHandle(message, response);
				}
				else
				{
					response.Message = "任务执行超时";
					actionTimeOutCallBack?.Invoke();
				}
			}
			else
			{
				response.Message = "执行任务不存在";
			}
			await Task.Yield();
			return response;
		}
		finally
		{
			CloseEvent(name);
		}
	}

	/// <summary>
	/// 消息处理
	/// </summary>
	private void EventHandle<T>(EventMessage eventMessage, EventParameterResponse<T> response)
	{
		response.Body = (T)(eventMessage.MessageBody ?? ((object)default(T)));
		response.Message = eventMessage.ErrorMsg ?? "执行成功";
		response.Code = eventMessage.State;
	}

	/// <summary>
	///
	/// </summary>
	/// <param name="name"></param>
	/// <returns></returns>
	public List<string> GetExcuteEventName(string name)
	{
		try
		{
			IEnumerable<string> result = Events.Select((KeyValuePair<string, EventMessage> u) => u.Key);
			if (!string.IsNullOrEmpty(name))
			{
				result = result.Where((string u) => u?.Contains(name) ?? false);
			}
			return result.ToList();
		}
		catch (Exception ex)
		{
			LoggerWrite.Error("查询报错", ex);
			return null;
		}
		finally
		{
		}
	}
}
